//==============================================================================================================
// ATMEL ATTINY85 SERIAL WATCHDOG PINOUT CONFIG:
//
//                          o-\/-+ 
//                         1|    |8  VCC 
//                         2|    |7  Reset OUT (connect to Nodo reset pin)
//           LED indicator 3|    |6  Serial RX (Input) (connect to Nodo TX)
//                    GND  4|    |5  Serial TX (Output) (optional, connect to PC for debugging)
//                          +----+ 
//==============================================================================================================

#include <SoftwareSerial.h>
#define SERIAL_RX_PIN 1
#define SERIAL_TX_PIN 0
#define RESET_PIN 2
#define LED_PIN 4
#define BAUD_RATE 19200
#define TIME_OUT_SEC 90
#define POST_RESET_DELAY 300 // 300 seconds

SoftwareSerial Serial(SERIAL_RX_PIN,SERIAL_TX_PIN);
byte resetCounter=0;
char buffer[10];
char serialchar;
byte counter=0;

void setup()
{
  pinMode(LED_PIN,OUTPUT);
  Serial.begin(BAUD_RATE);
  Serial.println("WD Ready");
  Serial.println(OSCCAL);
  OSCCAL=142; // may need som adjustedment for specific device, test device was 133 as factory default
              // each chip has it's own factory programmed value !!!
              // start with uncommenting this line and tune as needed.
}

void loop()
{
  counter=0;
  buffer[0]=0;

  if(Serial.available())
    {
      while(Serial.available())
        {
          serialchar=Serial.read();
          if (counter < 10)
            {
              buffer[counter]=serialchar;
              counter++;
            }
        }
      buffer[counter]=0;
      
      // Display serial input line
      for (byte x=0; x< counter; x++)
        Serial.write(buffer[x]);
      Serial.println();

      // check for 'WD!' pattern
      char *tempstr=(char*)malloc(10);
      if(GetArgv(buffer,tempstr,1))
        if (strcasecmp(tempstr,"WD!")==0)
         {  
           Serial.println("WD Received...");
           resetCounter=0;
           digitalWrite(LED_PIN,HIGH);
           delay(100);
           digitalWrite(LED_PIN,LOW);
         }
       free(tempstr);
    }
    
  Serial.print("RC:");
  Serial.println(resetCounter);
  resetCounter++;

  // in case of timeout, reset device  
  if (resetCounter > TIME_OUT_SEC)
  {
    Serial.println("WD Reset!");
    pinMode(RESET_PIN,OUTPUT);
    digitalWrite(RESET_PIN,LOW);
    delay(1000);
    digitalWrite(RESET_PIN,HIGH);
    pinMode(RESET_PIN,INPUT);
    resetCounter=0;
    for (int x=0; x < POST_RESET_DELAY; x++)
      {
        Serial.print("Sleeping:");
        Serial.println(int(x));
        delay(1000);
      }
  }
  delay(1000);
}

byte GetArgv(char *string, char *argv, int argc)
{
  int string_pos=0,argv_pos=0,argc_pos=0; 
  char c,d;

  while(string_pos<strlen(string))
  {
    c=string[string_pos];
    d=string[string_pos+1];

    if       (c==' ' && d==' '){}
    else if  (c==' ' && d==','){}
    else if  (c==',' && d==' '){}
    else if  (c==' ' && d>=33 && d<=126){}
    else if  (c==',' && d>=33 && d<=126){}
    else 
      {
      if(c!=' ' && c!=',')
        {
        argv[argv_pos++]=c;
        argv[argv_pos]=0;
        }          

      if(d==' ' || d==',' || d==0)
        {
        argv[argv_pos]=0;
        argc_pos++;

        if(argc_pos==argc)
          return string_pos+1;
          
        argv[0]=0;
        argv_pos=0;
        string_pos++;
      }
    }
    string_pos++;
  }
  return 0;
}
